package com.sky.controller.admin;

import com.sky.constant.JwtClaimsConstant;
import com.sky.dto.EmployeeDTO;
import com.sky.dto.EmployeeLoginDTO;
import com.sky.dto.EmployeePageQueryDTO;
import com.sky.entity.Employee;
import com.sky.properties.JwtProperties;
import com.sky.result.PageResult;
import com.sky.result.Result;
import com.sky.service.EmployeeService;
import com.sky.utils.JwtUtil;
import com.sky.vo.EmployeeLoginVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

/*
 * 员工管理的Controller
 * Controller的作用：接收前端发送请求传递过来的参数并且进行封装以及调用service层的方法进行查询数据库处理逻辑并且封装结果响应给前端请求
 */

/* @Slf4j是用作日志输出的，一般会在项目每个类的开头加入该注解并且使用log.info() */
@Slf4j
/*
 *@RestController 是一个组合注解，它结合了 @Controller 和 @ResponseBody 注解的功能（就相当于把两个注解组合在一起）
 *在使用 @RestController 注解标记的类中，每个方法的返回值都会以 JSON 或 XML 的形式直接写入 HTTP 响应体中，相当于在每个方法上都添加了 @ResponseBody 注解
 * */
@RestController
/*
 * @RequestMapping表示共享映射，如果没有指定请求方式，将接收GET、POST、HEAD、OPTIONS、PUT、PATCH、DELETE、TRACE、CONNECT所有的HTTP请求方式
 * @RequestMapping 注解可以在控制器类上和控制器类中的方法上使用。
 * @GetMapping、@PostMapping、@PutMapping、@DeleteMapping、@PatchMapping 都是HTTP方法特有的快捷方式@RequestMapping的变体，分别对应具体的HTTP请求方式的映射注解
 * */
@RequestMapping("/admin/employee")
@Api(tags = "员工管理相关的接口")
public class EmployeeController {
    /* @Autowired进行自动依赖注入，对类、成员变量、成员方法及构造方法进行标注，完成bean自动装配的工作*/
    @Autowired
    private EmployeeService employeeService;
    @Autowired
    private JwtProperties jwtProperties;

    /**
     * 员工登录
     *
     * @param employeeLoginDTO
     * @return Result.success(employeeLoginVO);
     * @info 接收前端传递过来的请求体参数 调用Service层的方法并且传递用户名和密码 Controller->Service->Mapper
     */
    @PostMapping("/login")
    @ApiOperation("员工登录")
    public Result<EmployeeLoginVO> login(@RequestBody EmployeeLoginDTO employeeLoginDTO) {
        // 调用service层的login方法，并且传递前端发送过来的请求体参数
        Employee employee = employeeService.login(employeeLoginDTO);
        /*生成JSONtoken */
        Map<String, Object> claims = new HashMap<>();
        claims.put(JwtClaimsConstant.EMP_ID, employee.getId());
        String token = JwtUtil.createJWT(jwtProperties.getAdminSecretKey(), jwtProperties.getAdminTtl(), claims);
        // 构建员工登录返回的数据格式
        EmployeeLoginVO employeeLoginVO = EmployeeLoginVO.builder().id(employee.getId()).userName(employee.getUsername()).name(employee.getName()).token(token).build();
        // 将员工登录的数据格式返回给前端请求的响应体中
        return Result.success(employeeLoginVO);
    }

    /**
     * 员工退出
     *
     * @param empty
     * @return Result
     * @info 给前端响应
     */
    @PostMapping("/logout")
    @ApiOperation("员工退出")
    public Result<String> logout() {
        return Result.success();
    }

    /**
     * 添加员工
     *
     * @param employeeDTO
     * @return Result
     * @info 接收前端传递过来的请求体参数，调用Service层的方法并且传递前端请求参数员工数据给Service层 Controller->Service->Mapper
     */
    @PostMapping("")
    @ApiOperation("添加员工")
    public Result addEmployee(@RequestBody EmployeeDTO employeeDTO, HttpServletRequest request) {
        // 调用Service层的方法
        employeeService.addEmployee(employeeDTO, request);
        // 响应结果给前端
        return Result.success();
    }

    /**
     * 查询所有员工(支持分页查询、条件查询)
     *
     * @param employeePageQueryDTO
     * @return PageResult
     * @info 接收前端传递过来的分页参数(路径参数)，调用Service层的方法并且传递前端分页路径参数给Service层 Controller->Service->Mapper
     */
    @GetMapping("/page")
    @ApiOperation("查询所有员工")
    public Result<PageResult> fetchAllEmployees(EmployeePageQueryDTO employeePageQueryDTO) {
        // 调用Service层的方法返回员工列表和员工总数
        PageResult pageResult = employeeService.fetchAllEmployees(employeePageQueryDTO);
        // 响应结果给前端
        return Result.success(pageResult);
    }

    /**
     * 删除员工
     *
     * @param id
     * @return void
     * @info 接收前端传递过来的路径参数员工ID，调用Service层的方法并且传递员工ID给Service层 Controller->Service->Mapper
     */

    @DeleteMapping("/{id}")
    @ApiOperation("删除员工")
    public Result deleteEmployee(@PathVariable Long id) {
        // 调用Service层的方法传递员工ID
        employeeService.deleteEmployee(id);
        // 响应结果给前端
        return Result.success();
    }

    /**
     * 修改员工的启用或者禁用状态
     *
     * @param status
     * @param id
     * @return void
     * @info 接收前端传递过来的status(路径参数)以及id(查询字符串参数)调用Service层的方法并且传递员工ID以及status给Service层 Controller->Service->Mapper
     */
    @PostMapping("/status/{status}")
    @ApiOperation("启用或禁用员工状态")
    public Result openOrCloseEmployeeStatus(@PathVariable int status, @RequestParam Long id) {
        // 调用Service层的方法传递员工ID以及员工的状态
        employeeService.openOrCloseEmployeeStatus(status, id);
        // 响应结果给前端
        return Result.success();
    }

    /**
     * 根据员工ID查询员工
     *
     * @param id
     * @return employee
     * @info 接收前端传递过来的员工id(路径参数)调用Service层的方法并且传递员工ID给Service层 Controller - > Service - > Mapper
     */
    @GetMapping("/{id}")
    @ApiOperation("查询员工")
    public Result<Employee> fetchEmployeeById(@PathVariable Long id) {
        // 调用Service层的方法传递员工ID以及员工的状态，并且响应结果给前端
        return Result.success(employeeService.fetchEmployeeById(id));
    }

    /**
     * 编辑员工
     *
     * @param employee
     * @return Result
     * @info 接收前端传递过来的员工信息(请求体参数)调用Service层的方法并且传递员工信息给Service层 Controller - > Service - > Mapper
     */
    @PutMapping("")
    @ApiOperation("编辑员工")
    public Result updateEmployee(@RequestBody EmployeeDTO employeeDTO) {
        employeeService.updateEmployee(employeeDTO);
        return Result.success();
    }
}
